﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data;
using System.Drawing;

namespace STKMIS
{
    public delegate void CellsDoubleClickHandler(object sender, DoubleClickEventArgs e);
    public delegate void OnErrorHandler(object sender, Exception e);
    public partial class MultiColumnsCombox : ComboBox
    {

        #region 成员变量
        private const int WM_LBUTTONDOWN = 0x201, WM_LBUTTONDBLCLK = 0x203;
        ToolStripControlHost dataGridViewHost;
        ToolStripControlHost textBoxHost;
        ToolStripDropDown dropDown;

        private string _keyWordsColumn = "";
        private string _displayMemberColumn = "";
        private string _valueMemberColumn = "";
        private string _selectedValue = "";
        private string m_Separator = "|";
        private string m_NullValue = "";
        private bool _isShowEvent = false;

        private bool m_blPopupAutoSize = false;


        #endregion
        #region 事件定义
        public event CellsDoubleClickHandler DoubleClickItemHandler;
        #endregion
        #region 构造函数
        public MultiColumnsCombox()
        {
            DrawDataGridView();
        }
        #endregion
        #region 属性
        [Description("空值时的默认值"), Browsable(true), Category("N8")]
        public string NullValue
        {
            set
            {
                m_NullValue = value;
            }
            get
            {
                return m_NullValue;
            }
        }
        [Description("查询关键字列名"), Browsable(true), Category("N8")]
        public string KeyWordsColumn
        {
            get
            {
                return _keyWordsColumn;
            }
            set
            {
                _keyWordsColumn = value;
            }
        }
        [Description("文本框显示字段列名"), Browsable(true), Category("N8")]
        public string DisplayMemberColumn
        {
            set
            {
                _displayMemberColumn = value;

            }
            get
            {
                return _displayMemberColumn;
            }
        }
        [Description("是否显示条件输入窗口"), Browsable(true), Category("N8")]
        public bool RowFilterVisible
        {
            set
            {
                dropDown.Items[0].Visible = value;
            }
            get
            {
                return dropDown.Items[0].Visible;
            }
        }
        [Description("取值字段名"), Browsable(true), Category("N8")]
        public string ValueMemberColumn
        {
            set
            {
                _valueMemberColumn = value;
            }
            get
            {
                return _valueMemberColumn;
            }
        }
        [Description("获取选择的值"), Browsable(true), Category("N8")]
        public string ComboxValue
        {
            set
            {
                _selectedValue = value;
            }
            get
            {
                return _selectedValue;
            }
        }
        public DataView DataView
        {
            get
            {
                DataTable dataTable = GetDataTableFromDataSource();
                if (dataTable == null)
                {
                    return null;
                }
                return dataTable.DefaultView;
            }
        }
        [Description("设置DataGridView属性"), Browsable(true), Category("N8")]
        public DataGridView DataGridView
        {
            get
            {
                return dataGridViewHost.Control as DataGridView;
            }
        }
        public TextBox TextBox
        {
            get
            {
                return textBoxHost.Control as TextBox;
            }
        }
        [Description("数据源"), Browsable(true), Category("N8")]
        public new Object DataSource
        {
            set
            {

                DataGridView.Columns.Clear();
                DataGridView.AutoGenerateColumns = false;
                this.DisplayColList();
                DataGridView.DataSource = value;
            }
            get
            {
                return DataGridView.DataSource;
            }
        }
        [Description("下拉表格尺寸是否为自动"), Browsable(true), Category("N8")]
        public bool PopupGridAutoSize
        {
            set
            {
                m_blPopupAutoSize = value;
            }
            get
            {
                return m_blPopupAutoSize;
            }
        }
        [Description("分割符号"), Browsable(true), Category("N8")]
        public string SeparatorChar
        {
            set
            {
                m_Separator = value;
            }
            get
            {
                return m_Separator;
            }
        }
        [Description("是否启用事件获取值"), Browsable(true), Category("N8")]
        public bool IsShowEvent
        {
            get { return _isShowEvent; }
            set { _isShowEvent = value; }
        }

        private List<ComboxGridViewColumns> _grvColumnsList;
        /// <summary>
        /// 显示列表参数
        /// </summary>
        public List<ComboxGridViewColumns> GrvColumnsList
        {
            get { return _grvColumnsList; }
            set { _grvColumnsList = value; }
        }
        #endregion
        #region 方法
        #region 绘制DataGridView以及下拉DataGridView
        private void DrawDataGridView()
        {
            DataGridView dataGridView = new DataGridView();
            dataGridView.BackgroundColor = SystemColors.ActiveCaptionText;
            dataGridView.BorderStyle = BorderStyle.None;
            dataGridView.ReadOnly = true;
            dataGridView.AllowUserToAddRows = false;
            dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            // dataGridView.RowsDefaultCellStyle.BackColor = Color.FromArgb(255, 255, 255);//第一行   
            dataGridView.BackgroundColor = System.Drawing.SystemColors.Control;
            dataGridView.AlternatingRowsDefaultCellStyle.BackColor = Color.FromArgb(231, 232, 239);//第二行   
            dataGridView.MultiSelect = false;
            dataGridView.GridColor = Color.FromArgb(207, 208, 216);//

            dataGridView.RowTemplate.Height = 25;//列宽
            dataGridView.AllowUserToAddRows = false;//无空行
            dataGridView.CellBorderStyle = DataGridViewCellBorderStyle.SingleVertical;
            dataGridView.RowHeadersVisible = false;
            dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
            dataGridView.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
            dataGridView.AllowUserToOrderColumns = true;
            dataGridView.AutoGenerateColumns = false;

            //dataGridView.DoubleClick += new EventHandler(dataGridView_DoubleClick);
            dataGridView.KeyDown += new KeyEventHandler(dataGridView_KeyDown);
            dataGridView.CellDoubleClick += new DataGridViewCellEventHandler(dataGridView_CellDoubleClick);

            //设置DataGridView的数据源
            Form frmDataSource = new Form();
            frmDataSource.Controls.Add(dataGridView);
            frmDataSource.SuspendLayout();
            dataGridView.Dock = DockStyle.Fill;
            dataGridViewHost = new ToolStripControlHost(dataGridView);

            dataGridViewHost.AutoSize = m_blPopupAutoSize;

            TextBox textBox = new TextBox();
            textBox.Width = this.Width;
            textBox.Height = this.Height;
            textBox.TextChanged += new EventHandler(textBox_TextChanged);
            textBox.KeyDown += new KeyEventHandler(textBox_KeyDown);
            textBoxHost = new ToolStripControlHost(textBox);
            textBoxHost.AutoSize = false;

            dropDown = new ToolStripDropDown();
            dropDown.Width = this.Width;
            dropDown.Items.Add(textBoxHost);
            dropDown.Items.Add(dataGridViewHost);
        }
        #endregion


        /// <summary>
        /// 弹出下拉表格并触发选择后事件
        /// </summary>
        /// <param name="e"></param>
        private void PopupGridView(EventArgs e)
        {
            if (DataGridView.SelectedRows.Count > 0)
            {
                DataGridViewRow dgvRow = DataGridView.CurrentRow;

                string strText = dgvRow.Cells[_displayMemberColumn].Value.ToString();
                this.Text = strText;
                this._selectedValue = dgvRow.Cells[_valueMemberColumn].Value.ToString();
                if (_isShowEvent)
                {
                    if (DoubleClickItemHandler != null)
                    {
                        DoubleClickEventArgs ex = new DoubleClickEventArgs(dgvRow.Index, -1, dgvRow);

                        //DoubleClickItemHandler(this, ex);
                        RaiseDoubleClickItem(this, ex);
                    }
                }
            }
            dropDown.Close();

        }
        #region 获取数据源
        /// <summary>
        /// 获取DataGridView数据源数据
        /// </summary>
        /// <returns></returns>
        private DataTable GetDataTableFromDataSource()
        {
            object dataSource = DataGridView.DataSource;
            return GetDataTableFromDataSource(dataSource);
        }
        /// <summary>
        /// 从DataGridView 获取数据表
        /// </summary>
        /// <returns></returns>
        private DataTable GetDataTableFromDataSource(object dataSource)
        {
            if (dataSource is DataTable)
            {
                return (DataTable)dataSource;
            }
            else if (dataSource is DataView)
            {
                return ((DataView)dataSource).Table;
            }
            else if (dataSource is BindingSource)
            {
                object bind = ((BindingSource)dataSource).DataSource;
                if (bind is DataTable)
                {
                    return (DataTable)bind;
                }
                else
                {
                    return ((DataView)bind).Table;
                }
            }
            else
            {
                return null;
            }
        }
        #endregion

        private void ShowDropDown()
        {
            if (dropDown != null)
            {
                if (DataView != null)
                {
                    DataView.RowFilter = "";
                    TextBox.Text = this.Text;
                    this.TextBox.SelectionStart = this.Text.Length;
                    textBoxHost.Width = 200;
                    dataGridViewHost.AutoSize = m_blPopupAutoSize;
                    int w = 0;
                    for (int i = 0; i < this.DataGridView.Columns.Count; i++)
                    {
                        if (this.DataGridView.Columns[i].Visible)
                        {
                            w += this.DataGridView.Columns[i].Width;
                        }
                    }
                    if (w < dataGridViewHost.Width)
                    {
                        w = dataGridViewHost.Width;
                    }
                    dataGridViewHost.Size = new Size(w, DropDownHeight);
                    dropDown.Show(this, 0, 0);
                    TextBox.Focus();
                }

            }
        }
        #region 事件

        private void dataGridView_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.Enter)
            {
                PopupGridView(e);
            }
        }
        /// <summary>
        /// 单元格双击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            string strText = (string)this.DataGridView.CurrentRow.Cells[_displayMemberColumn].Value;
            this.Text = strText;
            this._selectedValue = this.DataGridView.CurrentRow.Cells[_valueMemberColumn].Value.ToString();
            if (_isShowEvent)
            {
                if (DoubleClickItemHandler != null && e != null)
                {
                    DataGridViewRow dgvr = new DataGridViewRow();
                    dgvr = this.DataGridView.CurrentRow;
                    DoubleClickEventArgs ex = new DoubleClickEventArgs(e.RowIndex, e.ColumnIndex, dgvr);
                    //DoubleClickItemHandler(sender, ex);
                    RaiseDoubleClickItem(sender, ex);
                }
            }
            dropDown.Close();
        }

        /// <summary>
        /// 文本框内容发生变化事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textBox_TextChanged(object sender, System.EventArgs e)
        {
            DataView.RowFilter = GetRowFilterString(TextBox.Text);
        }
        /// <summary>
        /// 文本框键按下事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.Enter)
            {
                PopupGridView(e);
            }
            else if (e.KeyData == Keys.Down || e.KeyData == Keys.Up)
            {
                DataGridView.Focus();
            }
        }
        #endregion


        protected void OnDoubleClickItem(object sender, DoubleClickEventArgs e)
        {
            if (DoubleClickItemHandler != null)
            {
                if (_isShowEvent)
                {
                    DoubleClickItemHandler(sender, e);
                }
            }
        }

        protected virtual void RaiseDoubleClickItem(object sender, DoubleClickEventArgs e)
        {
            OnDoubleClickItem(sender, e);
        }

        /// <summary>
        /// 设置Filter过滤
        /// </summary>
        /// <param name="sText"></param>
        /// <returns></returns>
        private string GetRowFilterString(string sText)
        {
            string sFilter = "";
            if (_displayMemberColumn == String.Empty || _displayMemberColumn == null)
            {
                _displayMemberColumn = DataView.Table.Columns[0].ColumnName;
            }
            if (_keyWordsColumn == String.Empty)
            {
                _keyWordsColumn = _displayMemberColumn;
            }
            string[] sColumns = _keyWordsColumn.Split(',');
            foreach (string sColumn in sColumns)
            {
                sFilter += sColumn + " like " + "'%" + sText + "%'" + " or ";
            }
            sFilter = sFilter.Trim().TrimEnd("or".ToCharArray());
            return sFilter;
        }
        /// <summary>
        /// 设置GridView显示列
        /// </summary>
        private void DisplayColList()
        {

            foreach (ComboxGridViewColumns GrvColumnsInfo in this.GrvColumnsList)
            {
                DataGridViewColumn obj = new DataGridViewTextBoxColumn();

                obj.DataPropertyName = GrvColumnsInfo.DataPropertyName;
                obj.HeaderText = GrvColumnsInfo.HeaderText;
                obj.Name = GrvColumnsInfo.DataPropertyName;
                obj.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
                obj.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;
                obj.DefaultCellStyle.WrapMode = DataGridViewTriState.False;
                obj.Width = GrvColumnsInfo.Width;
                obj.Visible = GrvColumnsInfo.IsVisible;
                obj.Resizable = DataGridViewTriState.True;
                obj.ReadOnly = true;
                this.DataGridView.Columns.AddRange(new DataGridViewColumn[] { obj });
            }
        }

        #region 重写方法
        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);
            ShowDropDown();

            if (e.KeyData == Keys.Enter)
            {
                DataView.RowFilter = GetRowFilterString(Text);
                PopupGridView(null);
            }
        }

        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            if (char.IsDigit(e.KeyChar) || char.IsLetter(e.KeyChar))
            {
                this.TextBox.Text = e.KeyChar.ToString();
                this.TextBox.SelectionStart = this.TextBox.Text.Length;
                e.Handled = true;
            }
            base.OnKeyPress(e);
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_LBUTTONDBLCLK || m.Msg == WM_LBUTTONDOWN)
            {
                ShowDropDown();
                return;
            }
            base.WndProc(ref m);
        }
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (dropDown != null)
                {
                    dropDown.Dispose();
                    dropDown = null;
                }
            }
            base.Dispose(disposing);
        }
        #endregion
        #endregion
    }
    public class DoubleClickEventArgs : EventArgs
    {
        private int _rowIndex;
        private int _columnIndex;
        private object _value;

        public int RowIndex
        {
            get { return _rowIndex; }
            set { _rowIndex = value; }
        }
        public int ColumnIndex
        {
            get { return _columnIndex; }
            set { _columnIndex = value; }
        }
        public object Value
        {
            get { return _value; }
            set { _value = value; }
        }

        public DoubleClickEventArgs(int rowIndex, int columnIndex, object value)
            : base()
        {
            _rowIndex = rowIndex;
            _columnIndex = columnIndex;
            _value = value;
        }
    }
    public class ComboxGridViewColumns
    {
        /// <summary>
        /// 绑定字段
        /// </summary>
        public string DataPropertyName { get; set; }
        /// <summary>
        /// 表头
        /// </summary>
        public string HeaderText { get; set; }
        /// <summary>
        /// 是否展示
        /// </summary>
        public bool IsVisible { get; set; }

        /// <summary>
        /// 宽度
        /// </summary>
        public int Width { get; set; }

        public ComboxGridViewColumns(string dataPropertyName, string headerText)
        {
            this.DataPropertyName = dataPropertyName;
            this.HeaderText = headerText;
            this.IsVisible = true;
            this.Width = 100;
        }
        public ComboxGridViewColumns(string dataPropertyName, string headerText, bool isVisible)
        {
            this.DataPropertyName = dataPropertyName;
            this.HeaderText = headerText;
            this.IsVisible = isVisible;
            this.Width = 100;
        }
        public ComboxGridViewColumns(string dataPropertyName, string headerText, int width)
        {
            this.DataPropertyName = dataPropertyName;
            this.HeaderText = headerText;
            this.IsVisible = true;
            this.Width = width;
        }
        public ComboxGridViewColumns(string dataPropertyName, string headerText, bool isVisible, int width)
        {
            this.DataPropertyName = dataPropertyName;
            this.HeaderText = headerText;
            this.IsVisible = isVisible;
            this.Width = width;
        }
    }
}
